﻿package ua.mihaylenko.game.mahjongg.engine 
{
	import away3d.cameras.HoverCamera3D;
	import away3d.containers.Scene3D;
	import away3d.containers.View3D;
	import away3d.materials.BitmapMaterial;
	import away3d.materials.ColorMaterial;
	import away3d.materials.WireColorMaterial;
	import away3d.primitives.Cube;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.utils.Dictionary;
	import ua.mihaylenko.game.mahjongg.engine.mjcube.MJCube;
	/**
	 * ...
	 * @author Mihaylenko A.L.
	 */
	public class CMahjong extends EventDispatcher
	{
		static private const SIZE_OF_PIECE:int = 5
		private var _cOwner:DisplayObjectContainer;
		private var _cScene:Scene3D;
		private var _cCamera:HoverCamera3D;
		private var _cView:View3D;
		private var _bMove:Boolean;
		private var lastMouseX:int;
		private var lastMouseY:int;
		private var lastPanAngle:int;
		private var lastTiltAngle:int;
		private var _smcGameBackground:Sprite;
		private var _xData:XML;
		private var _iLevel:int;
		
		private var _xMax:int;
		private var _yMax:int;
		private var _zMax:int;
		
		private var _x:Number
		private var _y:Number
		
		private var _dctMJCubes:Dictionary;
		public function CMahjong() 
		{
			
		}
		public function innit($owner:DisplayObjectContainer, $xData:XML, iLevel:int=0, $bgColor:uint = 0x4FAFF7):void {
			if (!$owner) {
				throw new Error('Not set owner for mahjong controller game');
			}else if (!$xData) {
				throw new Error('Not set xml config for levels');
			}else {
				_cOwner = $owner;
				_xData = $xData;
				_iLevel = iLevel;
				var _smcGameBackground:Sprite = new Sprite();
				_smcGameBackground.graphics.beginFill($bgColor);
				_smcGameBackground.graphics.drawRect(0, 0, _cOwner.stage.stageWidth, _cOwner.stage.stageHeight);
				_smcGameBackground.graphics.endFill();
				_cOwner.addChild(_smcGameBackground);
				create3DEngine();
				innitGame();
			}
		}
		
		private function innitGame():void
		{
			_x = 0;
			_y = 0;
			_yMax = 0;
			_xMax = 0;
			_zMax = 0;
			_dctMJCubes = new Dictionary();
			for each(var xNode:XML in _xData.level[_iLevel].column) {
				parseColumn(xNode);
				_y += 1;
			}
			onResize();
		}
		private function parseColumn(xValue:XML):void {
			if (_yMax < _y)_yMax = _y;1
			_x = 0;
			for each(var xNode:XML in xValue.row) {
				var aRows:Array = String(xNode.@value).split(',');
				_x += 1;
				if (_xMax < _x)_xMax = _x;
				for (var z:int = 0;  z < aRows.length; z++ ) {
					if (_zMax > z)_zMax = z;
					if (Number(aRows[z])) {
						var cCube:MJCube = new MJCube();
						cCube.x = z * SIZE_OF_PIECE;
						cCube.y =  _x * SIZE_OF_PIECE;
						cCube.z = _y * SIZE_OF_PIECE;
						cCube.setMjId(_x, _y, z);
						cCube.width = SIZE_OF_PIECE;
						cCube.height = SIZE_OF_PIECE;
						cCube.depth = SIZE_OF_PIECE;
						cCube.segmentsW = 2;
						cCube.segmentsH = 2;
						_cScene.addChild(cCube);
						_dctMJCubes[_x.toString() + ':' + _y.toString() + ':' + z.toString()] = cCube;
					}
				}
				
			}
		}
		private function create3DEngine():void
		{
			/**
			 * Create camera 3d engine
			 */
				_cCamera = new HoverCamera3D();
				_cCamera.focus = 50;
				_cCamera.distance = 100;
				_cCamera.minTiltAngle = 10;
				_cCamera.maxTiltAngle = 90;
				
				_cCamera.panAngle = -90;
				_cCamera.tiltAngle = 20;
				_cCamera.hover(true);
			
			/**
			 * Create scene and viewer
			 */
			_cScene = new Scene3D();
			
			_cView = new View3D();
			
			_cView.scene = _cScene;
			_cView.camera = _cCamera;
			
			_cOwner.addChild(_cView);
		}
		
		private function startMoveScene(event:MouseEvent):void
		{
			
			lastPanAngle = _cCamera.panAngle;
			lastTiltAngle = _cCamera.tiltAngle;
			lastMouseX = _cOwner.stage.mouseX;
			lastMouseY = _cOwner.stage.mouseY;
			_bMove = true;
			_cOwner.stage.addEventListener(MouseEvent.MOUSE_UP, stopMoveScene);
			_cOwner.stage.addEventListener(Event.MOUSE_LEAVE, stopMoveScene);
		}
		
		private function stopMoveScene(e:Event):void 
		{
			_bMove = false;
			_cOwner.stage.removeEventListener(Event.MOUSE_LEAVE, stopMoveScene);
			_cOwner.stage.removeEventListener(MouseEvent.MOUSE_UP, stopMoveScene);
		}
		/**
		 * Start game( added game listeners and rendering)
		 */
		public function startGame():void
		{
			_cOwner.addEventListener(Event.ENTER_FRAME, updateRenderer);
			_cOwner.stage.addEventListener(MouseEvent.MOUSE_DOWN, startMoveScene);
			_cOwner.stage.addEventListener(Event.RESIZE, onResize);
		}
		
		/**
		 * Stop game( pause game and remove all game listeners)
		 */
		public function stopGame():void
		{
			_cOwner.removeEventListener(Event.ENTER_FRAME, updateRenderer);
			_cOwner.removeEventListener(MouseEvent.MOUSE_DOWN, startMoveScene);
		}
		
		private function updateRenderer(event:Event = null):void 
		{
			if (_bMove) {
				_cCamera.panAngle = 0.3 * (_cOwner.mouseX - lastMouseX) + lastPanAngle;
				_cCamera.tiltAngle = 0.3 * (_cOwner.mouseY - lastMouseY) + lastTiltAngle;
			}
			_cCamera.hover();
			_cView.render();
		}
		public function onResize(event:Event = null):void
		{
			_cView.x = _cOwner.stage.stageWidth / 2;
			_cView.y = _cOwner.stage.stageHeight / 2;
		}		
		
	}

}